package com.itheima.server.service;

import com.itheima.domain.bo.OptionsBo;
import com.itheima.domain.bo.QuestionsBo;
import com.itheima.domain.db.*;
import com.itheima.domain.vo.*;
import com.itheima.dubbo.api.*;
import com.itheima.server.interceptor.UserHolder;
import com.itheima.server.util.ConclusionUtil;
import com.itheima.server.util.CoverUtil;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 阿鹏
 * @date 2021/3/1 20:42
 */
@Service
public class TestSoulService {

    @Reference
    private QuestionsApi questionsApi;
    @Reference
    private QuestionsCategoryApi categoryApi;
    @Reference
    private QuestionsOptionApi optionApi;
    @Reference
    private QuestionsReportApi reportApi;
    @Reference
    private QuestionsLockApi lockApi;
    @Reference
    private UserInfoApi userInfoApi;

    /**
     * 问卷列表: 组装需要的数据即可
     */
    public ResponseEntity findQuestionsList() {
        // 获取当前用户
        Long userId = UserHolder.getUserId();

        List<QuestionsVo> voList = new ArrayList<>();

        // 查询所有的问卷
        List<QuestionsCategory> categories = categoryApi.findAll();
        if (!CollectionUtils.isEmpty(categories)) {
            for (QuestionsCategory category : categories) {
                QuestionsVo vo = new QuestionsVo();
                vo.setId(category.getId().toString());
                vo.setName(category.getName());
                vo.setCover(category.getCover());
                vo.setLevel(category.getLevel());
                vo.setStar(category.getStar());

                // 通过分类的id查询所有的问题
                List<Questions> questionsList = questionsApi.findListByCid(category.getId());


                // 封装QuestionsBo
                List<QuestionsBo> boList = new ArrayList<>();
                for (Questions questions : questionsList) {
                    QuestionsBo bo = new QuestionsBo();
                    bo.setId(questions.getId().toString());
                    bo.setQuestion(questions.getQuestion());

                    // 封装questionsBo下对应的options
                    List<QuestionsOption> optionList = optionApi.findListByQid(questions.getId());
                    List<OptionsBo> optionsBos = new ArrayList<>();
                    for (QuestionsOption option : optionList) {
                        OptionsBo optionsBo = new OptionsBo();
                        optionsBo.setId(option.getId().toString());
                        optionsBo.setOption(option.getQuestionsOption());
                        optionsBos.add(optionsBo);
                    }
                    bo.setOptions(optionsBos);
                    boList.add(bo);
                }

                vo.setQuestions(boList);

                // 判断当前用户的isLock
                QuestionsLock lock = lockApi.findByUserIdAndCid(userId, category.getId());
                if (lock == null) {
                    // 初始化lock表  设置当前用户的初级问题为unlock,其他问题为lock
                    lock = new QuestionsLock();
                    lock.setUserId(userId);
                    lock.setCid(category.getId());
                    if (category.getId() == 1) {
                        lock.setIsLock(0);
                    } else {
                        lock.setIsLock(1);
                    }
                    lockApi.saveInitLock(lock);
                }


                // 循环第一次解锁初级试题
                vo.setIsLock(0);
                QuestionsReport report = null;
                if (category.getId().longValue() > 1) {
                    // 如果到了中级的题，就要判断初级的report有没有
                    report = reportApi.findByCidAndUserId(lock.getCid() - 1, userId);
                    // 如果不是初级试题, 就判断有没有对应的报告,没有就不解锁
                    vo.setIsLock(report == null ? 1 : 0);
                }

                report = reportApi.findByCidAndUserId(lock.getCid(), userId);

                vo.setReportId(report == null ? null : report.getId().toString());


                voList.add(vo);
            }
        }

        return ResponseEntity.ok(voList);
    }

    /**
     * 保存问卷
     * 就是将条件拆开 保存到report表中
     * report表的字段 userId cid conclusion cover sumScore用于后期生成报告使用
     * 返回的数据 报告的id
     * <p>
     * 通过总分的区间来写入conclusion总结
     * 判断数据库是否有当前用户的哪个级别的报告
     * 为了判断是否是新增还是更新
     * 提交报告之后 记得将下一阶段的锁打开
     */
    public ResponseEntity saveQuestions(List<Answers> answers) {
        Long userId = UserHolder.getUserId();
        // 记录sumScore
        Integer sumScore = 0;
        String optionId = null;
        String questionId = null;

        for (Answers answer : answers) {
            // 选项的id
            optionId = answer.getOptionId();
            // 问题的id
            questionId = answer.getQuestionId();

            // 通过选项id查询数据库 计算总分数
            QuestionsOption option = optionApi.querySumScore(optionId);
            sumScore += option.getScore();
        }

        // 通过问题的id查询是什么等级的
        Questions questions = questionsApi.findById(questionId);
        QuestionsCategory category = categoryApi.queryCategoryById(questions.getCid());

        QuestionsReport questionsReport = reportApi.findByCidAndUserId(category.getId(), userId);
        Long reportId = 0L;
        if (questionsReport == null) {
            // 说明用户是第一次测试 要新增
            questionsReport = new QuestionsReport();
            questionsReport.setUserId(userId);
            questionsReport.setCid(category.getId());
            questionsReport.setCover(calculateCoverByScore(sumScore));
            questionsReport.setConclusion(calculateConclusionByScore(sumScore));
            questionsReport.setSumScore(sumScore);
            // 新增
            reportId = reportApi.saveReport(questionsReport);
        } else {
            // 说明用户是n次测试,要修改
            questionsReport.setSumScore(sumScore);
            questionsReport.setCover(calculateCoverByScore(sumScore));
            questionsReport.setConclusion(calculateConclusionByScore(sumScore));
            // 修改
            reportId = reportApi.updateReport(questionsReport);
        }

        // 通过等级选择性开启锁 ===能走到这里 说明报告已经提交或者修改了
        if (category.getId() == 1) {
            // 初级的 要修改中级的为不加锁
            QuestionsLock lock = lockApi.findByUserIdAndCid(userId, 2L);
            // 这里加了三元运算,直接写代码还没测,不确定前端保存完report以后会不会执行上个方法修改锁的状态,所以这里加上更保险
            lock.setIsLock(lock.getIsLock() == 1 ? 0 : 0); // 设置为解锁状态
            lockApi.updateQuestionsLock(lock);
        } else if (category.getId() == 2) {
            // 中级的 要修改高级的为不加锁
            QuestionsLock lock = lockApi.findByUserIdAndCid(userId, 3L);
            lock.setIsLock(lock.getIsLock() == 1 ? 0 : 0); // 设置为解锁状态
            lockApi.updateQuestionsLock(lock);
        }

        // 按照api文档返回id
        return ResponseEntity.ok(reportId.toString());
    }

    private String calculateConclusionByScore(Integer sumScore) {
        if (sumScore < 21) {
            return ConclusionUtil.under21();
        } else if (sumScore >= 21 && sumScore < 40) {
            return ConclusionUtil.under40();
        } else if (sumScore >= 40 && sumScore <= 55) {
            return ConclusionUtil.under55();
        } else {
            return ConclusionUtil.over56();
        }
    }

    private String calculateCoverByScore(Integer sumScore) {
        if (sumScore < 21) {
            return CoverUtil.under21();
        } else if (sumScore >= 21 && sumScore < 40) {
            return CoverUtil.under40();
        } else if (sumScore >= 40 && sumScore <= 55) {
            return CoverUtil.under55();
        } else {
            return CoverUtil.over56();
        }
    }

    /**
     * 查看结果方法
     * @param reportId 报告的id
     * @return 返回的参数有 conclusion,cover,List<dimensions(key, value)> List<similarYou(id, avatar)>
     *     dimensions 和 similarYou 都包含俩字段 封装vo
     */
    public ResponseEntity findResult(Long reportId) {
        // 通过reportId查找报告
        QuestionsReport report = reportApi.findById(reportId);

        // 创建vo 先封装report的数据
        ReportResultVo vo = new ReportResultVo();
        vo.setConclusion(report.getConclusion());
        vo.setCover(report.getCover());

        // 差dimension维度项（外向，判断，抽象，理性）和similarYou与你相似

        // 封装dimension
        List<Dimension> dimensions = new ArrayList<>();
        dimensions.add(new Dimension("外向", calculateDimension(report.getSumScore())));
        dimensions.add(new Dimension("判断", calculateDimension(report.getSumScore())));
        dimensions.add(new Dimension("抽象", calculateDimension(report.getSumScore())));
        dimensions.add(new Dimension("理性", calculateDimension(report.getSumScore())));
        // 放入vo中
        vo.setDimensions(dimensions);

        // 封装similarYou
        List<SimilarYou> similarYous = new ArrayList<>();
        // 这里逻辑比较简单，从报告表中查询所有的报告，取出userId, 判断当前用户的sumScore与其他的sumScore是否相同，
        // 相同：添加到相似的人   如果没有数据，随便返回几个人给他看
        List<QuestionsReport> reportList = reportApi.findAll();
        if (!CollectionUtils.isEmpty(reportList) && reportList.size() > 10) {
            // 如果数据库中有报告 这里的判断其实多余，因为走到这 至少有一个报告,因此多加入一个条件，至少10条我在遍历判断否则模拟推荐数据
            for (QuestionsReport questionsReport : reportList) {
                if (questionsReport.getUserId().longValue() == report.getUserId()) {
                    continue;
                }
                // 按照上边写的逻辑进行判断
                if (questionsReport.getSumScore().intValue() == report.getSumScore()) {
                    UserInfo userInfo = userInfoApi.findById(questionsReport.getUserId());
                    SimilarYou similarYou = new SimilarYou();
                    similarYou.setId(userInfo.getId().intValue());
                    similarYou.setAvatar(userInfo.getAvatar());
                    similarYous.add(similarYou);
                } else {
                    // 如果没有相同的，还是给你推个 就推129 架构师杨少
                    UserInfo userInfo = userInfoApi.findById(129L);
                    SimilarYou similarYou = new SimilarYou();
                    similarYou.setId(userInfo.getId().intValue());
                    similarYou.setAvatar(userInfo.getAvatar());
                    similarYous.add(similarYou);
                }

            }

        } else {
            String userId = "2,3,4,5,6,7";
            for (String id : userId.split(",")) {
                // 判断是不是当前用户
                if (!id.equals(userId.toString())) {
                    UserInfo userInfo = userInfoApi.findById(Long.valueOf(id));
                    SimilarYou similarYou = new SimilarYou();
                    similarYou.setId(userInfo.getId().intValue());
                    similarYou.setAvatar(userInfo.getAvatar());
                    similarYous.add(similarYou);
                }
            }
        }

        vo.setSimilarYou(similarYous);

        return ResponseEntity.ok(vo);
    }


    private String calculateDimension(Integer sumScore) {
        // 这里随机生成一些
        if (sumScore >= 0 && sumScore < 5) {
            return RandomUtils.nextInt(10, 40) + "%";
        } else if (sumScore >= 5 && sumScore < 10) {
            return RandomUtils.nextInt(40, 60) + "%";
        } else if (sumScore >= 10 && sumScore <= 20) {
            return RandomUtils.nextInt(60, 80) + "%";
        } else {
            return RandomUtils.nextInt(80, 100) + "%";
        }
    }
}
